#!/usr/bin/env python
# version: v0.1

import optparse, time, os, sys
import wx
from data_manager import *
from canvas import *
from log_object import *
from graph_manager import *
from color_manager import *

#current_dir = os.path.abspath(".")
current_dir = "./" 


class MainFrame(wx.Frame):
	def __init__(self, winsize):
		wx.Frame.__init__(self, None, -1, "Wall User Experience Analysis Tool", wx.Point(0,22), winsize)
		self.data_frame = None
		self.db_dir = current_dir + "db/"

		self.log_list =[]
		self.selected_case_list = []
		self.selected_user_list = []
		self.activeTime =  POINTER_ACTIVE_GAP 
		self.effectRange = EFFECTIVE_RANGE 

		self.test_period_list = []

		# create status bar
		#self.statusBar = self.CreateStatusBar()

		# create menu
		menuBar = wx.MenuBar()
		menuFile = wx.Menu()

		miScheme = menuFile.Append(-1, "&Switch Scheme\tCtrl-S", "Switch Scheme")
                self.Bind(wx.EVT_MENU, self.OnSwitchSceme, miScheme)

		miSave = menuFile.Append(-1, "&Save\tCtrl-A", "Save as")
		self.Bind(wx.EVT_MENU, self.OnSave, miSave)

		miExport = menuFile.Append(-1, "&Export\tCtrl-E", "Export")
		self.Bind(wx.EVT_MENU, self.OnExport, miExport)

		miTest = menuFile.Append(-1, "&Test\tCtrl-T", "Test")
		self.Bind(wx.EVT_MENU, self.OnTest, miTest)

		menuFile.AppendSeparator()

		miFileExit = menuFile.Append(-1, "&Exit\tCtrl-Q", "Exit")
		self.Bind(wx.EVT_MENU, self.OnExitButton, miFileExit)
		menuBar.Append(menuFile, "&File")
		self.SetMenuBar(menuBar)

		self.Window = DataCanvas(self, winsize)
		self.graph_mgr = GraphManager(self, self.Window) 
		self.color_mgr = ColorManager()

		wx.EVT_CLOSE(self, self.OnExitButton)

	def clearPanel(self):
		self.graph_mgr.clearCurrentGraphList()
		self.Window.clearPanel()

	def showCanvas(self):
		del self.selected_case_list
		self.selected_case_list = []
		del self.selected_user_list
		self.selected_user_list = []
		self.graph_mgr.clearCurrentGraphList()
		
		for log in self.log_list:
			log.analyze(self.activeTime)

		for log_obj in self.log_list :
			self.Window.addCase(log_obj.name)
			for pointer in log_obj.pointer_list :
				self.Window.addParcitipant(pointer.name)
		self.Show(True)
		self.data_frame.Show(False)
		self.Window.UpdateDrawing()

	def showDataManager(self):
		max = len(self.log_list)
		for i in range(max) :
			log_obj = self.log_list.pop()
			del log_obj
		self.Show(False)
		self.data_frame.Show(True)

	def OnSave(self, event):
		winx = -1
		winy = -1

		current_log = self.log_list[0]
		pointer = current_log.pointer_list[0]
		name = pointer.name + "-" + current_log.name + "-" + self.graph_mgr.graph_name 
		if self.graph_mgr.graph_name == "" : 
			name = "undefined"
		elif self.graph_mgr.graph_name == 'busy_graph' : 
			#self.Window.closeTab()
			#winx = current_log.duration * 30
			#winy = 350 
			#self.SetReSize(winx, winy)
			name = pointer.name + "-" + current_log.name + "-busy_graph" 
		elif self.graph_mgr.graph_name == 'heatmap_graph' or self.graph_mgr.graph_name == 'window_graph' : 
			name += "-" + self.graph_mgr.param_name
			# 8196 x 1024 - original size of CAVE2
			# winx = 4098 + 250
			# winy = (512 + 20) * 3 + 20

		self.Window.SaveDrawing(name)


	def SetReSize(self, winx, winy):
                win_size = (winx, winy)
                self.SetSize(win_size)
                self.Window.SetSize(win_size)
                self.Window.OnSize(None)
                self.SendSizeEvent()

	def OnTest(self, event):
		del self.test_period_list
		self.test_period_list = []

		self.graph_mgr.clearCurrentGraphList()
		self.graph_mgr.setCurrentGraph(TESTGRAPH, LOG_WINDOW_CHANGE)
		self.data_frame.test(first=True)
		#self.data_frame.test(first=False)

		total_period = 0
		idx = 0
		for a_log in self.log_list :
			test =self.test_period_list[idx]
			p = test[1] 
			total_period += (p - a_log.start_time)
			idx += 1 
		#print "total anal time=", total_period

	def OnExport(self, event):
		current_log = self.log_list[0]
		pointer = current_log.pointer_list[0]
		prefix = pointer.name + "-" + current_log.name + "-" 

		#cmd = "cp -f \"" + source_path + "\" \"" + dir + "\""
		#os.system(cmd)

		self.Window.closeTab()

		# test window 
		'''
		winx = 1580 
		winy = 850 
		self.graph_mgr.clearCurrentGraphList()
		self.SetReSize(winx, winy)
		name = "total-study-2-window" 
		self.graph_mgr.setCurrentGraph(TESTGRAPH, LOG_WINDOW_CHANGE)
		self.Window.SaveDrawing(name)
		'''

		# busy-window info graph
		winx = current_log.duration * 30 + 10
		winy = 1050 
		self.graph_mgr.clearCurrentGraphList()
		self.SetReSize(winx, winy)
		name = prefix + "busy_window_info_graph" 
		self.graph_mgr.setCurrentGraph(BUSYGRAPH, LOG_WINDOW_CHANGE)
		self.Window.SaveDrawing(name)

		return

		'''
		# busy graph
		winx = current_log.duration * 30
		winy = 350 
		self.graph_mgr.clearCurrentGraphList()
		self.SetReSize(winx, winy)
		name = prefix + "busy_graph" 
		self.graph_mgr.setCurrentGraph(BUSYGRAPH, LOG_POINTER_MOVE)
		self.Window.SaveDrawing(name)

		# heatmap mouse
		winx = 1580 
		winy = 620 
		#winx = 3160 
		#winy = 1240  
		self.graph_mgr.clearCurrentGraphList()
		self.SetReSize(winx, winy)
		name = prefix + "heatmap-pointer" 
		self.graph_mgr.setCurrentGraph(HEATMAP, LOG_POINTER_MOVE)
		self.Window.SaveDrawing(name)

		# heatmap section 
		name = prefix + "heatmap-section" 
		self.graph_mgr.clearCurrentGraphList()
		self.graph_mgr.setCurrentGraph(HEATMAP, LOG_SECTION)
		self.Window.SaveDrawing(name)

		# heatmap section data in 
		winx = 1580 
		winy = 620 
		self.graph_mgr.clearCurrentGraphList()
		self.SetReSize(winx, winy)
		name = prefix + "heatmap-section-datain" 
		self.graph_mgr.setCurrentGraph(HEATMAP, LOG_SECTION_DATAIN)
		self.Window.SaveDrawing(name)

		# vector mouse
		name = prefix + "vector-pointer"
		self.graph_mgr.clearCurrentGraphList()
		self.graph_mgr.setCurrentGraph(VECTORGRAPH, LOG_POINTER_MOVE)
		self.Window.SaveDrawing(name)

		# heatmap window 
		winx = 1580 
		winy = 850 
		self.graph_mgr.clearCurrentGraphList()
		self.SetReSize(winx, winy)
		name = prefix + "heatmap-window" 
		self.graph_mgr.setCurrentGraph(HEATMAP, LOG_WINDOW_CHANGE)
		self.Window.SaveDrawing(name)
		'''
		# space , number of windows
		winx = 1580 
		winy = 980  
		self.graph_mgr.clearCurrentGraphList()
		self.SetReSize(winx, winy)
		name = prefix + "no_of_windows"
		self.graph_mgr.setCurrentGraph(SPACEGRAPH, LOG_POINTER_MOVE)
		self.Window.SaveDrawing(name)
		return 

		# space window 
		winx = 1580 
		winy = 980  
		self.graph_mgr.clearCurrentGraphList()
		self.SetReSize(winx, winy)
		name = prefix + "space"
		self.graph_mgr.setCurrentGraph(SPACEGRAPH, LOG_WINDOW_CHANGE)
		self.Window.SaveDrawing(name)


		name = prefix + "window-dist-size"
		self.graph_mgr.clearCurrentGraphList()
		self.graph_mgr.setCurrentGraph(WINDOWGRAPH, LOG_WINDOW_DIS_SIZE)
		self.Window.SaveDrawing(name)

		name = prefix + "window-dist-lifetime"
		self.graph_mgr.clearCurrentGraphList()
		self.graph_mgr.setCurrentGraph(WINDOWGRAPH,LOG_WINDOW_DIS_TIME)
		self.Window.SaveDrawing(name)

		# window size
		winx = len(current_log.window_list) * 30
		winy = 980  
		self.graph_mgr.clearCurrentGraphList()
		self.SetReSize(winx, winy)
		name = prefix + "window-size"
		self.graph_mgr.setCurrentGraph(WINDOWGRAPH, LOG_WINDOW_SIZE)
		self.Window.SaveDrawing(name)

		name = prefix + "window-lifetime"
		self.graph_mgr.clearCurrentGraphList()
		self.graph_mgr.setCurrentGraph(WINDOWGRAPH, LOG_WINDOW_LIFETIME)
		self.Window.SaveDrawing(name)

		winx = 1920 
		winy = 1000 
		self.graph_mgr.clearCurrentGraphList()
		self.SetReSize(winx, winy)


	def getTagList(self):
		return self.Window._graphPanel.getTagList()

	def registerTag(self, tag):
		tokens = tag.split("-")
		for tag in tokens :
			self.Window._graphPanel.addTag(tag)

	def registerPeriod(self, tag): 
		tokens = tag.split("-")
		l =[] 
		for tag in tokens :
			l.append(float(tag))
		#print l
		self.test_period_list.append(l)

	def updateDrawing(self):
		self.Window.UpdateDrawing()

	def OnSwitchSceme(self, event):
		self.color_mgr.switchMode()
		self.Window.UpdateDrawing()

	def OnExitButton(self, event):
		for log in self.log_list :
			log._destroy()
		del self.log_list
		self.graph_mgr.destory()
		self.color_mgr.destory()
		app.ExitMainLoop()

	def createDataFrame(self, winsize):
		self.data_frame = DataFrame(self, (winsize[0], winsize[1]), (0,22))

	def createLog(self, start, duration, participants, name, date, display):
		log_obj = Log(start, duration, participants, name, date, display)
		self.log_list.append(log_obj)
		return log_obj

	def setDisplayTimeRange(self, start, end):
		self.Window.setDisplayTimeRange(start, end)

	def setActiveTime(self, gap):
		self.activeTime = gap
		for log in self.log_list:
			log.analyze(gap)

	def setEffectRange(self, value):
		self.effectRange = value 

	def setCurrentGraph(self, type, param1):
		self.graph_mgr.setCurrentGraph(type, param1)
		self.updateDrawing()

	def clearCurrentGraphList(self):
		self.graph_mgr.clearCurrentGraphList()

	def addParticipant(self, title):
		self.selected_user_list.append(title)
		self.graph_mgr.setNoOfUsers(len(self.selected_user_list))

	def deleteParticipant(self, title):
		self.selected_user_list.remove(title)
		self.graph_mgr.setNoOfUsers(len(self.selected_user_list))

	def isSelectedUser(self, title):
		for user in self.selected_user_list:
			if user == title :
				return True
		return False

	def addCase(self, title):
		self.selected_case_list.append(title)

	def deleteCase(self, title):
		self.selected_case_list.remove(title)

	def isSelectedCase(self, title):
		for case in self.selected_case_list:
			if case == title :
				return True
		return False

	def getColor(self, idx):
		return self.color_mgr.getColor(idx)

	def getBackgroundColor(self):
		return self.color_mgr.getBackgroundColor()

	def getForegroundColor(self):
		return self.color_mgr.getForegroundColor()


class AnalysisApp(wx.App):
	def __init__(self, cfg=current_dir+"default.cfg"):
		self.cfgfile = cfg
		wx.App.__init__(self,0)

	def createWindow(self):
		#winx = 1280 
		#winy = 780 
		winx = 1920 
		winy = 1000 
		self.frame = MainFrame((winx, winy))
		self.SetTopWindow(self.frame)
		self.frame.createDataFrame((winx, winy))

		self.frame.Show(False)
		self.frame.data_frame.Show(True)


def get_commandline_options():
	parser = optparse.OptionParser()
	h = "need user id"
	parser.add_option("-u", "--user", dest="user", help=h, default=None)

	f = "log file name"
	parser.add_option("-f", "--file", dest="filename", help=h, default=None)

	return parser.parse_args()

if __name__ == "__main__":
	if os.access(current_dir + '/db/', os.F_OK) == False :
		os.mkdir(current_dir + '/db/')

        app = AnalysisApp()
	app.createWindow()
        app.MainLoop()

	'''	
	(options, args) = get_commandline_options()
	current_user = options.user

	filename = options.filename 
	out_filename = filename[8:]

	log_file = open(current_dir + filename, "r")
	logdata = []
	out_file = open(current_dir + options.user + "_" + out_filename, "a+")

	count =0
	while True :
		line = log_file.readline()
		if len(line) == 0 :
			break
		logdata = line.split()
		token_count = len(logdata) 
		if token_count > 0:
			token = logdata[0]
			if token != '[' : 
				out_file.write(line)
			else :
				#['[', '1391742897.95', ']', 'POINTER', 'NEW', 'mouse', '192.168.0.31:Sanghwa']
				#['[', '1391742992.35', ']', 'POINTER', 'MOVE', '192.168.0.28:KSY', '1439', '149']
				#POINTER CLICK 192.168.31.1:Mere 640 300
				#POINTER RELEASE 192.168.31.1:Mere 701 305
				#POINTER REMOVE mouse 192.168.0.31:Sanghwa
				type = logdata[3] 
				if type == 'POINTER' : 
					sub_type = logdata[4] 
					user = []
					if sub_type == 'NEW' or sub_type == 'REMOVE': 
						user = logdata[6]  
					else:
						user = logdata[5]  
					if user == current_user: 
						out_file.write(line)
					del user
				del logdata[:]

	out_file.close()
	log_file.close()
	'''	

